/**
 * DateUtil.java
 * Created at 2015-11-6
 * Created by Codegen
 * Copyright (C) 2015 BROADTEXT SOFTWARE, All rights reserved.
 */
package com.wisdytech.common.utils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>
 * ClassName: DateUtil
 * </p>
 * <p>
 * Description: 时间操作Util类
 * </p>
 * <p>
 * Author: liujie
 * </p>
 * <p>
 * Date: 2017-02-15
 * </p>
 */
public class DateUtil {
    
    /**
     * 一周天数
     */
    public static final int MAX_DAYS_IN_WEEK = 7;
    /**
     * 一个月设定为跨服最多6周
     */
    public static final int MAX_WEEKS_IN_MONTH = 6;
    /**
     * 一年366天
     */
    public static final int DAYS_IN_YEAR_1 = 366;
    /**
     * 一年365天
     */
    public static final int DAYS_IN_YEAR_2 = 365;
    
    /** 数字31 */
    public static final int INT_THIRTY_ONE = 31;
    
    /**
     * 日志
     */
    private static Log log = LogFactory.getLog(DateUtil.class);

    /**
     * 日期格式到天
     */
    private static SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * yyyy-MM
     */
    private static SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");

    /**
     * yyyy-MM-dd HH:mm:ss
     */
    private static final String DEFAULT_DATETIME_MASK = "yyyy-MM-dd HH:mm:ss";

    /**
     * yyyy-MM-dd
     */
    private static final String DEFAULT_DATE_MASK = "yyyy-MM-dd";

    

    /**
     * <p>
     * Description: 解析指定格式的日期
     * </p>
     * 
     * @param dateStr 日期字符串
     * @param dateMask 日期格式
     * @return 日期
     */
    public static Date getDate(String dateStr, String dateMask) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat dateFormat; 
        dateFormat = new SimpleDateFormat(dateMask);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + dateMask + "'");
        }

        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 返回给定格式的日期字符串
     * @param date 日期
     * @param dateMask 日期格式
     * @return 日期字符串
     * @author zhangwei
     */
    public static String getDateStr(Date date, String dateMask) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateMask);
        return sdf.format(date);
    }

    /**
     * <p>Description: 获取默认日期</p>
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date getDefaultDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_MASK);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + DEFAULT_DATE_MASK + "'");
        }

        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    /**
     * <p>Description: 获取默认日期</p>
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date getMonthDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        /*SimpleDateFormat dateFormat = new SimpleDateFormat(monthFormat);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + monthFormat + "'");
        }*/

        Date date = null;
        try {
            date = monthFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    /**
     * <p>Description: 获取默认日期</p>
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date getDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + DEFAULT_DATETIME_MASK + "'");
        }

        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    /**
     * <p>Description: 获取默认日期字符串  yyyy-MM-dd HH:mm:ss 格式</p>
     * @param date 日期
     * @return 日期字符串
     */
    public static String getDefaultDateStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATETIME_MASK);
        return sdf.format(date);
    }

    /**
     * <p>Description: 获取默认开始日期</p>
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date getDefaultDateBegin(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + DEFAULT_DATETIME_MASK + "'");
        }

        Date date = null;
        try {

            if (dateStr.length() > 10) {
                dateStr = dateStr.substring(0, 10);
            }

            date = dateFormat.parse(dateStr + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * <p>Description: 获取默认结束日期</p>
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date getDefaultDateEnd(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + dateStr + "' to date with mask '" + DEFAULT_DATETIME_MASK + "'");
        }

        Date date = null;
        try {
            if (dateStr.length() > 10) {
                dateStr = dateStr.substring(0, 10);
            }
            date = dateFormat.parse(dateStr + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 
     * <p>Description: 获取当天开始日期时间</p>
     * @return date
     */
    public static Date getTodayTimeBegin() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);
        Date date = new Date();
        String dateStr = dateFormat.format(date);
        try {
            dateStr = dateStr.substring(0, 10);
            date = dateFormat.parse(dateStr + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 
     * <p>Description: 获取当天日期 最后时间</p>
     * @return date
     */
    public static Date getTodayTimeEnd() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);
        Date date = new Date();
        String dateStr = dateFormat.format(date);
        try {
            dateStr = dateStr.substring(0, 10);
            date = dateFormat.parse(dateStr + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * <p>
     * Description: 当前月的起始时间
     * </p>
     * 
     * @return 当前月的起始时间
     */
    public static Date getCurrentMonthTimeBegin() {
        SimpleDateFormat dateFormat;
        dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);
        Calendar calendar;
        calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date date = new Date();
        String dateStr;
        try {
            dateStr = dateFormat.format(calendar.getTime()).substring(0, 10);
            date = dateFormat.parse(dateStr + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * <p>
     * Description: 当前月的结束时间
     * </p>
     * 
     * @return 当前月的结束时间
     */
    public static Date getCurrentMonthTimeEnd() {
        SimpleDateFormat dateFormat;
        dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_MASK);
        Calendar calendar;
        calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date date = new Date();
        String dateStr;
        try {
            dateStr = dateFormat.format(calendar.getTime()).substring(0, 10);
            date = dateFormat.parse(dateStr + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 返回yyyy-MM-dd格式的日期字符串
     * 
     * @return 日期字符串
     * @author zhangwei
     */
    public static String getCurDateDefaultStr() {
        Date curDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_MASK);
        return sdf.format(curDate);
    }

    /**
     * 返回yyyy-MM-dd格式的日期字符串
     * 
     * 
     * @param date 日期转化成字符串
     * @return 日期字符串 yyyy-MM-dd
     * @author zhangwei
     */
    public static String dateToStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_MASK);
        return sdf.format(date);
    }

    /**
     * 获取当前年月，格式yyyy-MM
     * 
     * @return Date
     */
    public static String getCurrentTimeYyyyMmStr() {
        return monthFormat.format(new Date());
    }

    /**
     * <p>
     * Description: 获取参数日期之前的日期字符串数组
     * </p>
     * 
     * @param date 日期
     * @return 日期字符串数组
     */
    public static String[] getBeforeDefaultDateArr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_MASK);

        Date monthStart = getMonthStart(date);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int index = calendar.get(Calendar.DAY_OF_MONTH);

        String[] dateArr;
        dateArr = new String[index];
        int num = 0;

        while (!monthStart.after(date)) {
            dateArr[num++] = sdf.format(monthStart);
            monthStart = getNext(monthStart);
        }
        return dateArr;
    }

    /**
     * <p>
     * Description: 根据日期获取当前月的第一天
     * </p>
     * 
     * @param date 日期
     * @return 当前月第一天
     */
    public static Date getMonthStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, (1 - index));
        return calendar.getTime();
    }

    /**
     * <p>
     * Description: 根据日期获取当前月的最后天
     * </p>
     * 
     * @param date 日期
     * @return 当前月最后天
     */
    public static Date getMonthEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, (-index));
        return calendar.getTime();
    }

    /**
     * <p>
     * Description: 根据日期获取第二天的日期
     * </p>
     * 
     * @param date 日期
     * @return 第二天的日期
     */
    public static Date getNext(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, 1);
        return calendar.getTime();
    }

    /**
     * <p>
     * Description: 根据日期获取第二天的日期
     * </p>
     * 
     * @param date 日期
     * @return 第二天的日期
     */
    public static Date getYesterday(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * <p>
     * Description: 获取与当前日期相间隔的的日期
     * </p>
     * 
     * @param date 日期
     * @param day 间隔天数
     * @return 日期
     */
    public static Date getDayTime(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 显示两个时间段的每一天 格式yyyy-MM-dd
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return dates
     * @exception e
     */
    public static List<String> displayBetweenTwoDay(String startTime, String endTime) {
        List<String> dates;
        dates = new ArrayList<String>();
        try {
            Date start;
            start = dayFormat.parse(startTime);
            Date end;
            end = dayFormat.parse(endTime);
            Calendar calendar;
            calendar = new GregorianCalendar();
            calendar.setTime(start);
            while (calendar.getTime().before(end)) {
                dates.add(dayFormat.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
            dates.add(dayFormat.format(end));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dates;
    }

    /**
     * 显示两个时间段的每一月 格式yyyy-MM
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return dates
     * @exception e
     */
    public static List<String> displayBetweenTwoMonth(String startTime, String endTime) {
        List<String> dates;
        dates = new ArrayList<String>();
        try {
            Date start;
            start = monthFormat.parse(startTime);
            Date end;
            end = monthFormat.parse(endTime);
            Calendar calendar;
            calendar = new GregorianCalendar();
            calendar.setTime(start);
            while (calendar.getTime().before(end)) {
                dates.add(monthFormat.format(calendar.getTime()));
                calendar.add(Calendar.MONTH, 1);
            }
            dates.add(monthFormat.format(end));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dates;
    }


    /**
     * 说明：周显示逻辑，第一周从本年的第一个周一开始计算 2016年是52周
     * 
     * @param date 日期
     * @return 周数
     * @author liniansheng
     */
    public static int getWeekOfYear(Date date) {
        Calendar calendar;
        calendar = Calendar.getInstance();
        // 每周以周一开始
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 每年的第一周必须大于或等于7天，否则就算上一年的最后一周
        calendar.setMinimalDaysInFirstWeek(DateUtil.MAX_DAYS_IN_WEEK);
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);

    }

    /**
     * 
     * <p>
     * Description: 准确获得周几
     * </p>
     * 
     * @param calendar calendar对象
     * @author liniansheng
     * @return 周几
     */
    public static int getDayOfWeek(Calendar calendar) {
        // 每周以周一开始
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 每年的第一周必须大于或等于7天，否则就算上一年的最后一周
        calendar.setMinimalDaysInFirstWeek(DateUtil.MAX_DAYS_IN_WEEK);
        boolean isFirstSunday;
        isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.MONDAY);
        //获取周几
        int weekDay;
        weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        //若一周第一天为星期天，则-1
        if (isFirstSunday) {
            weekDay = weekDay - 1;
            if (weekDay == 0) {
                weekDay = 7;
            }
        }
        return weekDay;
    }

    /**
     * 得到某年某周的第一天
     * 
     * @param year 年份
     * @param week 周数
     * @author liniansheng
     * @return 周开始日期
     */
    public static Date getFirstDayOfWeek(int year, int week) {
        Calendar c;
        c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);
        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, week * MAX_DAYS_IN_WEEK);
        return getFirstDayOfWeek(cal.getTime());
    }

    /**
     * 得到某年某周的最后一天
     * 
     * @param year 年份
     * @param week 周数
     * @author liniansheng
     * @return 周开始日期
     */
    public static Date getLastDayOfWeek(int year, int week) {
        Calendar c;
        c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);
        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, week * MAX_DAYS_IN_WEEK);
        return getLastDayOfWeek(cal.getTime());
    }

    /**
     * 取得指定日期所在周的第一天
     * 
     * @param date 日期
     * @return 开始日期
     * @author liniansheng
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c;
        c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday 
        return c.getTime();
    }

    /**
     * 取得指定日期所在周的最后一天
     * 
     * @param date 日期
     * @return 周最后的日期
     * @author liniansheng
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c;
        c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, (c.getFirstDayOfWeek() + MAX_DAYS_IN_WEEK - 1)); // Sunday 
        return c.getTime();
    }
    
    /**
     * 取得业务上的该年的周数
     * 
     * @param year 日期
     * @return 周数
     * @author liniansheng
     */
    public static int getWeekCounntOfYear(String year) {
        Calendar calendar;
        calendar = Calendar.getInstance();
        // 每周以周一开始
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 每年的第一周必须大于或等于7天，否则就算上一年的最后一周
        calendar.setMinimalDaysInFirstWeek(MAX_DAYS_IN_WEEK);
        //取得year-12-31号所在的周
        calendar.set(Integer.valueOf(year), Calendar.DECEMBER, INT_THIRTY_ONE);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }
    
    /**
     * 
     * <p>Description: 日期转string</p>
     * @param date 日期
     * @return string
     */
    public static String toString(Date date) {
        if (date == null) {
            return "";
        }
        Timestamp t;
        t = new Timestamp(date.getTime());
        return t.toString();
    }
    
    
    /**
     * 
     * <p>Description: 秒转换为小时</p>
     * @param second 秒
     * @param scale 精确度
     * 
     * @return
     */
    public static Double second2Hour(Long second,int scale){
        if(null == second || second<=0){
            return 0.00;
        }
        
        BigDecimal b1 = new BigDecimal(second);
        //除数
        BigDecimal b2 = new BigDecimal(3600);
        
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        
    }
    
    /**
     * 
     * <p>Description: 秒转换为小时</p>
     * @param second 秒
     * @param scale 精确度
     * 
     * @return
     */
    public static Double second2Hour(BigDecimal second,int scale){
        if(null == second || second.doubleValue()<=0){
            return 0.00;
        }
        
//        BigDecimal b1 = new BigDecimal(second);
        //除数
        BigDecimal b2 = new BigDecimal(3600);
        
        return second.divide(b2, scale, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        
    }




}
